package org.dromara.pay.controller;


import cn.dev33.satoken.annotation.SaIgnore;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.pay.config.WxPayConfig;
import org.dromara.pay.service.TopUpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * 回调控制器
 *
 * @author zlj
 */
@Validated
@RequiredArgsConstructor
@RestController
@Slf4j
@SaIgnore
@RequestMapping("/notify")
public class NotifyController {
    @Autowired
    private WxPayConfig wxPayConfig;
    private final TopUpService topUpService;

    /**
     * 小程序支付回调
     */
    @PostMapping(value = "/xcxPayNotify")
    public String xcxPayNotify(@RequestBody String xmlData) {
        log.info("下单微信支付异步回调通知处理:{}", xmlData);
        WxPayOrderNotifyResult result;
        try {
            result = wxPayConfig.wxMiniService().parseOrderNotifyResult(xmlData);
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())) {
                log.error(xmlData);
                throw new WxPayException("微信支付-通知失败！");
            }
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
                log.error(xmlData);
                throw new WxPayException("微信支付-通知失败！");
            }
        } catch (WxPayException e) {
            log.error("微信支付-通知失败", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
        log.info("微信支付-通知成功！");
        log.info(xmlData);
        //处理订单信息
        log.info("下单微信返回，订单编号{}", result.getOutTradeNo());
        log.info("下单微信返回，订单编号：{},微信流水号：", result.getOutTradeNo(), result.getTransactionId());
        //逻辑处理
        topUpService.processWxOrders(result);
        return WxPayNotifyResponse.success("OK");
    }

    /**
     * app支付回调
     */
    @PostMapping(value = "/appPayNotify")
    public String appPayNotify(@RequestBody String xmlData) {
        log.info("下单微信支付异步回调通知处理:{}", xmlData);
        WxPayOrderNotifyResult result;
        try {
            result = wxPayConfig.wxAppService().parseOrderNotifyResult(xmlData);
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())) {
                log.error(xmlData);
                throw new WxPayException("微信支付-通知失败！");
            }
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
                log.error(xmlData);
                throw new WxPayException("微信支付-通知失败！");
            }
        } catch (WxPayException e) {
            log.error("微信支付-通知失败", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
        log.info("微信支付-通知成功！");
        log.info(xmlData);
        //处理订单信息
        log.info("下单微信返回，订单编号{}", result.getOutTradeNo());
        log.info("下单微信返回，订单编号：{},微信流水号：", result.getOutTradeNo(), result.getTransactionId());
        //逻辑处理
        topUpService.processWxOrders(result);
        return WxPayNotifyResponse.success("OK");
    }

    /**
     * 小程序退款回调
     */
    @PostMapping("/xcxRefund")
    public String xcxRefund(@RequestBody String xmlData) {
        log.info("退款微信支付异步回调通知处理:{}", xmlData);
        WxPayRefundNotifyResult result;
        try {
            result = wxPayConfig.wxMiniService().parseRefundNotifyResult(xmlData);
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
                log.error(xmlData);
                throw new WxPayException("微信退款-通知失败！");
            }
            if (!WxPayConstants.RefundStatus.SUCCESS.equals(result.getReqInfo().getRefundStatus())) {
                log.error(xmlData);
                throw new WxPayException("微信退款-通知失败");
            }
        } catch (WxPayException e) {
            log.error("微信退款-通知失败", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
        WxPayRefundNotifyResult.ReqInfo reqInfo = result.getReqInfo();
        log.info("退款成功，编号：{}，退款时间：{}", reqInfo.getOutTradeNo(), reqInfo.getSuccessTime());
        // 退款成功业务处理
        topUpService.processWxRefund(reqInfo);
        return WxPayNotifyResponse.success("OK");
    }

    /**
     * 微信app退款回调
     */
    @PostMapping("/appRefund")
    public String appRefund(@RequestBody String xmlData) {
        log.info("退款微信支付异步回调通知处理:{}", xmlData);
        WxPayRefundNotifyResult result;
        try {
            result = wxPayConfig.wxAppService().parseRefundNotifyResult(xmlData);
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
                log.error(xmlData);
                throw new WxPayException("微信退款-通知失败！");
            }
            if (!WxPayConstants.RefundStatus.SUCCESS.equals(result.getReqInfo().getRefundStatus())) {
                log.error(xmlData);
                throw new WxPayException("微信退款-通知失败");
            }
        } catch (WxPayException e) {
            log.error("微信退款-通知失败", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
        WxPayRefundNotifyResult.ReqInfo reqInfo = result.getReqInfo();
        log.info("退款成功，编号：{}，退款时间：{}", reqInfo.getOutTradeNo(), reqInfo.getSuccessTime());
        // 退款成功业务处理
        topUpService.processWxRefund(reqInfo);
        return WxPayNotifyResponse.success("OK");
    }
}
